//
//  RecordVideoViewController.m
//  CoolTennisBall
//
//  Created by ZYK on 16/2/23.
//  Copyright © 2016年 CoolLang. All rights reserved.
//

#import "RecordVideoViewController.h"
#import "MZTimerLabel.h"
#import <AVFoundation/AVFoundation.h>
#import <AssetsLibrary/AssetsLibrary.h>
#import "RecordSportView.h"
#import "CommunicationManager.h"
#import "ChartItem.h"
#import "KRVideoPlayerController.h"
#import "TrackVideo.h"
#import "IDFileManager.h"
#import <DateTools/DateTools.h>
#import "TrackRecordView.h"
#import "SportViewController.h"
#import "UIImage+Resize.h"

typedef void(^PropertyChangeBlock)(AVCaptureDevice *captureDevice);

@interface RecordVideoViewController ()<AVCaptureFileOutputRecordingDelegate>//视频文件输出代理
@property (strong,nonatomic) AVCaptureSession *captureSession;//负责输入和输出设置之间的数据传递
@property (strong,nonatomic) AVCaptureDeviceInput *captureDeviceInput;//负责从AVCaptureDevice获得输入数据
@property (strong,nonatomic) AVCaptureMovieFileOutput *captureMovieFileOutput;//视频输出流
@property (strong,nonatomic) AVCaptureVideoPreviewLayer *captureVideoPreviewLayer;//相机拍摄预览图层
@property (assign,nonatomic) BOOL enableRotation;//是否允许旋转（注意在视频录制过程中禁止屏幕旋转）
@property (assign,nonatomic) CGRect *lastBounds;//旋转的前大小
@property (assign,nonatomic) UIBackgroundTaskIdentifier backgroundTaskIdentifier;//后台任务标识

@property (weak, nonatomic) IBOutlet UIButton *takeButton;//拍照按钮
@property (weak, nonatomic) IBOutlet UIView *timeView;

@property (strong, nonatomic) MZTimerLabel *timer;
@property (copy, nonatomic) NSURL *videoStringUrl;

@property (nonatomic, strong) TrackVideo *video;
@property (nonatomic, strong) NSDate *startDate;

@property (weak, nonatomic) IBOutlet TrackRecordView *speedTrackView;
@property (weak, nonatomic) IBOutlet TrackRecordView *strengthTrackView;
@property (weak, nonatomic) IBOutlet TrackRecordView *arcTrackView;
@property (weak, nonatomic) IBOutlet UIButton *connectingButton;

@end

@implementation RecordVideoViewController

#pragma mark - Getter/Setter

- (TrackVideo *)video
{
    if (_video == nil) {
        _video = [[TrackVideo alloc] init];
    }
    
    return _video;
}

#pragma mark - ViewLifeCircle

- (void)viewDidLoad
{
    [super viewDidLoad];
    
    [self preferredInterfaceOrientationForPresentation];
    
    [self configureLocalization];
    [self configureAVCapture];
    [self configureTimeView];
    [self configureArcViews];
    [self registerNotification];
    
}
-(void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    [self.captureSession startRunning];
}

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
}

-(void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    [self.captureSession stopRunning];
}

//移除通知
-(void)dealloc
{
    [self removeNotification];
}

#pragma mark - Notification

- (void)registerNotification
{
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeviceDisconnect:) name:kLGPeripheralDidDisconnect object:nil];
    
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleDeviceConnected:) name:kLGPeripheralDidConnect object:nil];
}

- (void)handleDeviceDisconnect:(NSNotification *)notification
{
    [self connectingButtonShow:YES];
}

- (void)handleDeviceConnected:(NSNotification *)notification
{
    [self connectingButtonShow:NO];
    
    [self performSelector:@selector(enterRealTimeMode) withObject:nil afterDelay:1.0f];
}

- (void)connectingButtonShow:(BOOL)isShowing
{
    [UIView animateWithDuration:0.5f animations:^{
        self.connectingButton.alpha = isShowing ? 1.0f : 0;
    }];
}

#pragma mark - Localization

- (void)configureLocalization
{
    self.speedTrackView.nameLabel.text = NSLocalizedString(@"Speed", nil);
    self.strengthTrackView.nameLabel.text = NSLocalizedString(@"Strength", nil);
    self.arcTrackView.nameLabel.text = NSLocalizedString(@"Radian", nil);
    [self.connectingButton setTitle:NSLocalizedString(@"Reconnecting…", nil) forState:UIControlStateNormal];
}

#pragma mark - Bluetooth

- (void)enterRealTimeMode
{
    __weak RecordVideoViewController *weakSelf = self;
    
    [[CommunicationManager shareInstance] performOperationType:OperationTypeReadRunTimeData object:nil completionBlock:^(BOOL success, id feedbackData) {
        if (!success) {
            return;
        }
        [BTHandler handleRuntimeData:feedbackData withCompletion:^(BOOL success, SportPoseType actionType, NSInteger speed, NSInteger strength, NSInteger radian, NSInteger hitball, NSInteger topBottomBall, NSInteger forebackBall) {
            if (success) {
                NSLog(@"实时运动模式设置成功");
                ChartItem *item = [[ChartItem alloc] init];
                item.poseType = actionType;
                item.maxSpeed = [NSString stringWithFormat:@"%d",(int)speed];
                item.strength = [NSString stringWithFormat:@"%d",(int)strength];
                item.arc = [NSString stringWithFormat:@"%d",(int)radian];
                item.hasHitTheBall = hitball == 0 ? NO : YES;
                item.handBallType = topBottomBall == 0 ? HandBallTypeUp : HandBallTypeDown;
                item.handDirectionType = forebackBall == 0 ? HandDirectionTypeForeward : HandDirectionTypeBackward;
                [weakSelf configureForGaugeWithItem:item];
                
                NSInteger swingSecond = (NSInteger)[[NSDate date] secondsLaterThan:self.startDate];                
                
                VideoTrackItem *swingItem = [[VideoTrackItem alloc] initWithSpeed:speed strength:strength arc:radian swingSecond:swingSecond];
                [self.video.videoTrackItems addObject:swingItem];
                
            }else{
                [weakSelf enterRealTimeMode];
            }
        }];
    }];
    
    [[NSNotificationCenter defaultCenter] postNotificationName:SportViewControllerShouldRefreshNotification object:nil];
}

- (void)configureForGaugeWithItem:(ChartItem *)item
{
    [self.speedTrackView.arcView updateChartByCurrent:@([item.maxSpeed integerValue])];
    [self.strengthTrackView.arcView updateChartByCurrent:@((NSInteger)round([item.strength integerValue]*11.0/100))];
    [self.arcTrackView.arcView updateChartByCurrent:@([item.arc integerValue])];
}

- (void)enterWaitingMode
{
    [[CommunicationManager shareInstance] performOperationType:OperationTypeQuitRunTime object:nil completionBlock:^(BOOL success, id feedbackData) {
        if (success) {
            NSLog(@"退出实时");
        }
    }];
}

#pragma mark - Private Method

- (void)configureArcViews
{
    self.speedTrackView.arcView.total = @200;
    self.speedTrackView.arcView.duration = 1;
    self.speedTrackView.arcView.lineWidth = @6;
    self.speedTrackView.arcView.circleBackgroundColor = [UIColor colorWithWhite:1 alpha:0.1];
    self.speedTrackView.arcView.countingLabel.textColor = [UIColor whiteColor];
    self.speedTrackView.arcView.strokeColor = [UIColor colorWithHex:0x79B9EB];
    self.speedTrackView.arcView.countingLabel.font = [UIFont boldSystemFontOfSize:21.0f];
    [self.speedTrackView.arcView strokeChart];
    
    self.strengthTrackView.arcView.total = @20;
    self.strengthTrackView.arcView.duration = 1;
    self.strengthTrackView.arcView.lineWidth = @6;
    self.strengthTrackView.arcView.countingLabel.textColor = [UIColor whiteColor];
    self.strengthTrackView.arcView.circleBackgroundColor = [UIColor colorWithWhite:1 alpha:0.1];
    self.strengthTrackView.arcView.strokeColor = [UIColor colorWithHex:0xF06FA5];
    self.strengthTrackView.arcView.countingLabel.font = [UIFont boldSystemFontOfSize:21.0f];
    [self.strengthTrackView.arcView strokeChart];
    
    self.arcTrackView.arcView.total = @360;
    self.arcTrackView.arcView.duration = 1;
    self.arcTrackView.arcView.lineWidth = @6;
    self.arcTrackView.arcView.countingLabel.textColor = [UIColor whiteColor];
    self.arcTrackView.arcView.circleBackgroundColor = [UIColor colorWithWhite:1 alpha:0.1];
    self.arcTrackView.arcView.strokeColor = [UIColor colorWithHex:0xF8C353];
    self.arcTrackView.arcView.countingLabel.font = [UIFont boldSystemFontOfSize:21.0f];
    [self.arcTrackView.arcView strokeChart];
}

//退出录制界面
- (IBAction)quitButtonAction:(UIButton *)sender
{
    if ([self.captureMovieFileOutput isRecording]) {
        [self takeButtonClick:nil];
    } else {
        [self dismissViewControllerAnimated:YES completion:nil];
    }
}

//屏幕横屏
- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return UIInterfaceOrientationLandscapeRight;
}

 //初始化会话
- (void)configureAVCapture{
        _captureSession = [[AVCaptureSession alloc]init];
    if ([_captureSession canSetSessionPreset:AVCaptureSessionPreset1280x720]) {//设置分辨率
        _captureSession.sessionPreset = AVCaptureSessionPreset1280x720;
    }
    
    //获得输入设备
    AVCaptureDevice *captureDevice=[self getCameraDeviceWithPosition:AVCaptureDevicePositionBack];//取得后置摄像头
    if (!captureDevice) {
        NSLog(@"取得后置摄像头时出现问题.");
        return;
    }
    //添加一个音频输入设备
    AVCaptureDevice *audioCaptureDevice = [[AVCaptureDevice devicesWithMediaType:AVMediaTypeAudio] firstObject];
    
    
    NSError *error=nil;
    //根据输入设备初始化设备输入对象，用于获得输入数据
    _captureDeviceInput = [[AVCaptureDeviceInput alloc]initWithDevice:captureDevice error:&error];
    if (error) {
        NSLog(@"取得设备输入对象时出错，错误原因：%@",error.localizedDescription);
        return;
    }
    AVCaptureDeviceInput *audioCaptureDeviceInput=[[AVCaptureDeviceInput alloc]initWithDevice:audioCaptureDevice error:&error];
    if (error) {
        NSLog(@"取得设备输入对象时出错，错误原因：%@",error.localizedDescription);
        return;
    }
    //初始化设备输出对象，用于获得输出数据
    _captureMovieFileOutput=[[AVCaptureMovieFileOutput alloc]init];
    
    //将设备输入添加到会话中
    if ([_captureSession canAddInput:_captureDeviceInput]) {
        [_captureSession addInput:_captureDeviceInput];
        [_captureSession addInput:audioCaptureDeviceInput];
        AVCaptureConnection *captureConnection = [_captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo];
        
        captureConnection.videoOrientation = [self videoOrientationFromCurrentDeviceOrientation];
        if ([captureConnection isVideoStabilizationSupported ]) {
            captureConnection.preferredVideoStabilizationMode =AVCaptureVideoStabilizationModeAuto;
        }
        
        
    }
    
    //将设备输出添加到会话中
    if ([_captureSession canAddOutput:_captureMovieFileOutput]) {
        [_captureSession addOutput:_captureMovieFileOutput];
    }
    
    //创建视频预览层，用于实时展示摄像头状态
    _captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:self.captureSession];
    
    CALayer *layer = self.view.layer;
    layer.masksToBounds = YES;
    
    _captureVideoPreviewLayer.connection.videoOrientation
    = [self videoOrientationFromCurrentDeviceOrientation];
    _captureVideoPreviewLayer.frame = CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.height, [UIScreen mainScreen].bounds.size.width);
    _captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;//填充模式
    //将视频预览层添加到界面中
    [layer insertSublayer:_captureVideoPreviewLayer atIndex:0];
    _enableRotation=NO;
    [self addNotificationToCaptureDevice:captureDevice];
}

- (void)configureTimeView{
    self.timer = [[MZTimerLabel alloc] initWithFrame:self.timeView.bounds];
    self.timer.timerType = MZTimerLabelTypeStopWatch;
    [self.timeView addSubview:self.timer];
    self.timer.timeLabel.backgroundColor = [UIColor clearColor];
    self.timer.timeLabel.font = [UIFont systemFontOfSize:15.0f];
    self.timer.timeLabel.textColor = [UIColor whiteColor];
    self.timer.timeLabel.textAlignment = NSTextAlignmentCenter;
    self.timer.resetTimerAfterFinish = YES;
}

//录制视频的屏幕旋转
- (AVCaptureVideoOrientation)videoOrientationFromCurrentDeviceOrientation {
    return AVCaptureVideoOrientationLandscapeRight;
}

#pragma mark - 通知
/**
 *  给输入设备添加通知
 */
-(void)addNotificationToCaptureDevice:(AVCaptureDevice *)captureDevice{
    //注意添加区域改变捕获通知必须首先设置设备允许捕获
    [self changeDeviceProperty:^(AVCaptureDevice *captureDevice) {
        captureDevice.subjectAreaChangeMonitoringEnabled = YES;
    }];
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    //捕获区域发生改变
    [notificationCenter addObserver:self selector:@selector(areaChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
}

//移除录像功能通知
-(void)removeNotificationFromCaptureDevice:(AVCaptureDevice *)captureDevice{
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:captureDevice];
}
/**
 *  移除所有通知
 */
-(void)removeNotification{
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    [notificationCenter removeObserver:self];
}

-(void)addNotificationToCaptureSession:(AVCaptureSession *)captureSession{
    NSNotificationCenter *notificationCenter= [NSNotificationCenter defaultCenter];
    //会话出错
    [notificationCenter addObserver:self selector:@selector(sessionRuntimeError:) name:AVCaptureSessionRuntimeErrorNotification object:captureSession];
}

/**
 *  设备连接成功
 *
 *  @param notification 通知对象
 */
-(void)deviceConnected:(NSNotification *)notification{
    NSLog(@"设备已连接...");
}
/**
 *  设备连接断开
 *
 *  @param notification 通知对象
 */
-(void)deviceDisconnected:(NSNotification *)notification{
    NSLog(@"设备已断开.");
}
/**
 *  捕获区域改变
 *
 *  @param notification 通知对象
 */
-(void)areaChange:(NSNotification *)notification{
    NSLog(@"捕获区域改变...");
}

/**
 *  会话出错
 *
 *  @param notification 通知对象
 */
-(void)sessionRuntimeError:(NSNotification *)notification{
    NSLog(@"会话发生错误.");
}

/**
 *  取得指定位置的摄像头
 *
 *  @param position 摄像头位置
 *
 *  @return 摄像头设备
 */
-(AVCaptureDevice *)getCameraDeviceWithPosition:(AVCaptureDevicePosition )position{
    NSArray *cameras= [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
    for (AVCaptureDevice *camera in cameras) {
        if ([camera position] == position) {
            return camera;
        }
    }
    return nil;
}

/**
 *  改变设备属性的统一操作方法
 *
 *  @param propertyChange 属性改变操作
 */
-(void)changeDeviceProperty:(PropertyChangeBlock)propertyChange{
    AVCaptureDevice *captureDevice= [self.captureDeviceInput device];
    NSError *error;
    //注意改变设备属性前一定要首先调用lockForConfiguration:调用完之后使用unlockForConfiguration方法解锁
    if ([captureDevice lockForConfiguration:&error]) {
        propertyChange(captureDevice);
        [captureDevice unlockForConfiguration];
    }else{
        NSLog(@"设置设备属性过程发生错误，错误信息：%@",error.localizedDescription);
    }
}

#pragma mark - IBAction Method
//开始和停止录制
- (IBAction)takeButtonClick:(UIButton *)sender {
    //根据设备输出获得连接
    AVCaptureConnection *captureConnection = [self.captureMovieFileOutput connectionWithMediaType:AVMediaTypeVideo];
    //根据连接取得设备输出的数据
    if (![self.captureMovieFileOutput isRecording]) {
        self.startDate = [NSDate date];
        [self enterRealTimeMode];
        [self.timer start];
        [self.takeButton setImage:[UIImage imageNamed:@"trackPattern_icon_stop"] forState:UIControlStateNormal];
        self.enableRotation = NO;
        //如果支持多任务则则开始多任务
        if ([[UIDevice currentDevice] isMultitaskingSupported]) {
            self.backgroundTaskIdentifier = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:nil];
        }
        //预览图层和视频方向保持一致
        captureConnection.videoOrientation = [self.captureVideoPreviewLayer connection].videoOrientation;
        
        NSString *outputFielPath=[NSTemporaryDirectory() stringByAppendingString:@"myMovie.mov"];
        NSLog(@"save path is :%@",outputFielPath);
        NSURL *fileUrl=[NSURL fileURLWithPath:outputFielPath];
        NSLog(@"fileUrl:%@",fileUrl);
        
        [self.captureMovieFileOutput startRecordingToOutputFileURL:fileUrl recordingDelegate:self];
        
    }
    else{
        [self enterWaitingMode];
        [self.timer pause];
        [self.timer reset];
        [self.takeButton setImage:[UIImage imageNamed:@"trackPattern_icon_begin"] forState:UIControlStateNormal];
        [self.captureMovieFileOutput stopRecording];//停止录制
    }
}

#pragma mark - 视频输出代理
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didStartRecordingToOutputFileAtURL:(NSURL *)fileURL fromConnections:(NSArray *)connections{
    NSLog(@"开始录制...");
}
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error{
    NSLog(@"视频录制完成.");
    
    FUIAlertView *alertView = [[FUIAlertView alloc] initWithTitle:NSLocalizedString(@"Do you want to save this Live Video？", nil) message:NSLocalizedString(@"If the device is interrupted while recording, the missed real-time data will be recovered once saved.", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"Delete", nil) otherButtonTitles:NSLocalizedString(@"Save", nil), nil];
    [alertView customizeAppearance];
    [alertView show];
    
    alertView.onOkAction = ^{
        //视频录入完成之后在后台将视频存储到相簿
        self.enableRotation = NO;
        
        IDFileManager *manager = [[IDFileManager alloc] init];
        NSString *videoPath = [manager documentPathFromCopyFile:outputFileURL];
        NSLog(@"保存视频路径:%@", videoPath);
        
        self.video.path = videoPath;
        self.video.name = NSLocalizedString(@"Live Video", nil);
        self.video.creatDate = [NSDate date];
        
        // 存储视频缩略图路径
        NSData *imageData = UIImageJPEGRepresentation([self.video videoImage], 0.5);
        NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES).lastObject;
        
        self.video.imagePath = [NSString stringWithFormat:@"videoImage-%@.png",[NSUUID UUID].UUIDString];
        
        NSString *imagePath = [documentPath stringByAppendingPathComponent:self.video.imagePath];
        NSError *error = nil;
        BOOL writeSucc = [imageData writeToFile:imagePath options:0 error:&error];
        
        NSLog(@"图片写入:%zd error%@",writeSucc,error);
        
        if (self.videoBlock) {
            self.videoBlock(self.video);
        }
        
        [self dismissViewControllerAnimated:YES completion:nil];
        
        /*
        UIBackgroundTaskIdentifier lastBackgroundTaskIdentifier = self.backgroundTaskIdentifier;
        self.backgroundTaskIdentifier = UIBackgroundTaskInvalid;
        ALAssetsLibrary *assetsLibrary = [[ALAssetsLibrary alloc]init];
        [assetsLibrary writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) {
            if (error) {
                
                NSLog(@"保存视频到相簿过程中发生错误，错误信息：%@",error.localizedDescription);
            }
            NSLog(@"outputUrl:%@",outputFileURL);
            self.videoStringUrl = outputFileURL;
            [[NSFileManager defaultManager] removeItemAtURL:outputFileURL error:nil];
            if (lastBackgroundTaskIdentifier != UIBackgroundTaskInvalid) {
                [[UIApplication sharedApplication] endBackgroundTask:lastBackgroundTaskIdentifier];
                
            }
            
            NSLog(@"成功保存视频到相簿.");
            
        }];
         */
    };
}


#pragma mark - System Method
//限制屏幕横屏和录制视频横屏
-(BOOL)shouldAutorotate{
    return self.enableRotation;
}

@end
